package io.renren.modules.biz.service.impl;

import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.common.validator.Assert;
import io.renren.modules.biz.dao.SendPacketDao;
import io.renren.modules.biz.entity.BalanceDetailEntity;
import io.renren.modules.biz.entity.CountDto;
import io.renren.modules.biz.entity.GrabPacketEntity;
import io.renren.modules.biz.entity.MemberEntity;
import io.renren.modules.biz.entity.SendPacketEntity;
import io.renren.modules.biz.service.BalanceDetailService;
import io.renren.modules.biz.service.GrabPacketService;
import io.renren.modules.biz.service.MemberService;
import io.renren.modules.biz.service.SendPacketService;
import io.renren.modules.sys.service.SysConfigService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("sendPacketService")
public class SendPacketServiceImpl extends ServiceImpl<SendPacketDao, SendPacketEntity> implements SendPacketService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	MemberService memberService;

	@Autowired
	BalanceDetailService balanceDetailService;

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	GrabPacketService grabPacketService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String id = (String) params.get("id");
		String mobile = (String) params.get("mobile");
		String memberId = (String) params.get("memberId");
		String startDate = (String) params.get("startDate");
		String endDate = (String) params.get("endDate");
		if (StringUtils.isBlank(memberId) && StringUtils.isNotBlank(mobile)) {
			MemberEntity entity = memberService.selectOne(new EntityWrapper<MemberEntity>().eq("mobile", mobile));
			if (entity == null || entity.getId() == null) {
				memberId = "-1";
			} else {
				memberId = entity.getId().toString();

			}
		}
		Page<SendPacketEntity> page = this.selectPage(new Query<SendPacketEntity>(params).getPage(),
				new EntityWrapper<SendPacketEntity>().eq(StringUtils.isNotBlank(id), "id", id).eq(StringUtils.isNotBlank(memberId), "member_id", memberId).gt(StringUtils.isNotBlank(startDate), "create_time", startDate).le(StringUtils.isNotBlank(endDate), "create_time", endDate));

		return new PageUtils(page);
	}

	@Override
	public CountDto sumPacketAmount(String memberId, String mobile, String startDate, String endDate) {
		CountDto result = baseMapper.sumPacketAmount(memberId, mobile, startDate, endDate);
		if (result == null) {
			result = new CountDto();
			result.setSumOne(0D);
			result.setSumTwo(0D);
		} else {
			if (result.getSumOne() == null) {
				result.setSumOne(0D);
			}
			if (result.getSumTwo() == null) {
				result.setSumTwo(0D);
			}
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void returnPacket() {
		Date now = new Date();
		List<SendPacketEntity> list = this.selectList(new EntityWrapper<SendPacketEntity>().setSqlSelect("id,balance_amount,member_id,is_robot").eq("status", ProjectConstant.PACKET_STATUS_INITIAL)
				.le("create_time", DateUtils.addDateMinutes(now, -sysConfigService.getValueI(ConfigConstant.PACKET_EXPIRE))));
		if (CollectionUtils.isNotEmpty(list)) {

			List<MemberEntity> members = new ArrayList<MemberEntity>();
			List<BalanceDetailEntity> details = new ArrayList<BalanceDetailEntity>();
			List<Long> ids = new ArrayList<Long>();

			for (SendPacketEntity send : list) {

				if (send.getBalanceAmount() < 0) {
					logger.error("数据异常,红包被超额抢");
					continue;
				}
				ids.add(send.getId());

				if (send.getIsRobot() == ProjectConstant.COMMON_NO) {

					MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id,balance,version").eq("id", send.getMemberId()));
					member.setBalance(DecimalUtils.add(member.getBalance(), send.getBalanceAmount()));
					member.setUpdateTime(now);
					members.add(member);

					BalanceDetailEntity detail = new BalanceDetailEntity();
					detail.setBalanceChange(send.getBalanceAmount());
					detail.setMemberId(send.getMemberId());
					detail.setType(ProjectConstant.ORDER_TYPE_RETURN);
					detail.setDescription("未抢完红包退回");
					detail.setCreateTime(now);
					detail.setPacketId(send.getId());
					details.add(detail);
				}
			}

			if (CollectionUtils.isNotEmpty(members)) {
				Assert.isTrue(memberService.updateBatchById(members), "批量退回红包失败");
			}

			SendPacketEntity entity = new SendPacketEntity();
			entity.setStatus(ProjectConstant.PACKET_STATUS_RETURN);
			this.update(entity, new EntityWrapper<SendPacketEntity>().in("id", ids));
			if (CollectionUtils.isNotEmpty(details)) {
				balanceDetailService.insertBatch(details);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delRobotPacket() {
		List<Long> packetIds = baseMapper.onlyRobotPacketIds(DateTime.now().minusMinutes(270).toString("yyyy-MM-dd HH:mm:ss"), DateTime.now().minusHours(2).toString("yyyy-MM-dd HH:mm:ss"));
		if (CollectionUtils.isEmpty(packetIds)) {
			return;
		}
		logger.info("删除仅机器人抢发的红包:" + packetIds.size());
		grabPacketService.delete(new EntityWrapper<GrabPacketEntity>().in("send_packet_id", packetIds));
		this.deleteBatchIds(packetIds);
	}
}
